﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Input;

namespace ClassicJukebox
{
    public class WindowWithKeypadSupport : Window
    {
        private Thread keypad;
        private bool keypadThreadRunning = true;

        public static readonly RoutedEvent PreviewKeypadDownEvent;

        static WindowWithKeypadSupport()
        {
            WindowWithKeypadSupport.PreviewKeypadDownEvent = EventManager.RegisterRoutedEvent(
                "PreviewKeypadDown", RoutingStrategy.Bubble,
                typeof(KeypadEventHandler), typeof(WindowWithKeypadSupport));
        }

        public WindowWithKeypadSupport() :
            base()
        {
            Closing += new System.ComponentModel.CancelEventHandler(this.WindowWithKeypadSupport_Closing);
            this.keypad = new Thread(new ThreadStart(delegate
                {
                    int previousKeyValue = -1;
                    while (this.keypadThreadRunning)
                    {
                        int keyValue = PortAccess.Input(0x378 + 1) & 0x78;
                        if (keyValue != previousKeyValue)
                        {
                            if (keyValue == 0x78)
                            {
                                // KeypadReleased
                            }
                            else
                            {
                                Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                    (SendOrPostCallback)delegate
                                    {
                                        KeypadEventArgs e = new KeypadEventArgs(WindowWithKeypadSupport.PreviewKeypadDownEvent, this);
                                        e.Key = this.CreateKeyFromIOPortValue(keyValue);
                                        base.RaiseEvent(e);
                                    }, null);
                            }
                            previousKeyValue = keyValue;
                        }
                        Thread.Sleep(100);
                    }
                }));
            this.keypad.Start();
        }

        private void WindowWithKeypadSupport_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            this.keypadThreadRunning = false;
            this.keypad.Abort();
        }

        public event RoutedEventHandler PreviewKeypadDown
        {
            add
            {
                base.AddHandler(WindowWithKeypadSupport.PreviewKeypadDownEvent, value);
            }
            
            remove
            {
                base.RemoveHandler(WindowWithKeypadSupport.PreviewKeypadDownEvent, value);
            }
        }

        private Key CreateKeyFromIOPortValue(int value)
        {
            if ((value & 0x40) == 0x00)
            {
                return Key.Left;
            }
            if ((value & 0x20) == 0x00)
            {
                return Key.Right;
            }
            if ((value & 0x10) == 0x00)
            {
                return Key.Up;
            }
            if ((value & 0x08) == 0x00)
            {
                return Key.Down;
            }
            return Key.Enter;
        }
    }
}
